home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / asmutil / asm_n_z.zip / WHEREIS.ASM < prev    next >
Assembly Source File  |  1987-05-05  |  12KB  |  518 lines

  1.     name    whereis
  2.     title    'WHEREIS -- find file'
  3.     page    55,132
  4. ;
  5. ; WHEREIS -- find file in directory structure
  6. ; by John Scotia, first published in Softalk/IBM
  7. ; modified by Ray Duncan
  8. ;
  9. lf    equ    0ah            ;ASCII line feed
  10. cr    equ    0dh            ;ASCII carriage return
  11. ff    equ    0ch            ;ASCII form feed
  12. tab    equ    09h
  13. eom    equ    '$'            ;end of message flag
  14. ;
  15.                     ;Program Segment Prefix
  16. default_fcb equ    05ch
  17. command    equ    80h     
  18. default_dta equ    080h
  19. ;
  20. ;
  21.  
  22. ; This is the format for the DOS Data Transfer Area used when DOS 2.0    
  23. ; searches for a file match in directories.                
  24.  
  25. DTA    STRUC
  26.     RESERVED    DB    21 DUP (?)
  27.     ATTRIBUTE    DB    0
  28.     TIME        DW    0
  29.     DATE        DW    0
  30.     SIZE        DD    0
  31.     NAME_FOUND    DB    13 DUP (?)
  32. DTA    ENDS
  33.  
  34. cseg    segment    para public 'CODE'
  35.  
  36.     assume     cs:cseg,ds:data,es:data,ss:stack
  37.  
  38.     page
  39.  
  40. ; This is the main program that sets up the initial conditions for    
  41. ; SDIR which, in turn, does a recursive search.        
  42. ;                                    
  43. ; Reads:    PATH_NAME                        
  44. ; Writes:    FILE_NAME                        
  45. ; Calls:    SDIR                    
  46.  
  47. whereis    proc    far
  48.  
  49.     push    ds            ;save final return
  50.     xor    ax,ax
  51.     push    ax
  52.     mov    bp,sp            ;save pointer to final return
  53.                     ; in case we want to exit
  54.                     ; inside recursive routine
  55.  
  56.     mov    ax,data            ;make data segment addressable
  57.     mov    es,ax            ;via ES
  58.  
  59.     call    infile            ;get name of search target
  60.  
  61.     mov    ax,data            ;make data segment addressable
  62.     mov    ds,ax            ;via DS
  63.     jnc    whereis1        ;jump if filename was ok
  64.                     ;filename was missing,
  65.     mov    dx,offset msg1        ;print error message and exit
  66.     mov    ah,9
  67.     int    21h
  68.     ret
  69. whereis1:
  70.     mov    ah,30h            ;check DOS version
  71.     int    21h
  72.     cmp    al,2
  73.     jae    whereis2        ;proceed, DOS 2.0 or greater
  74.     mov    dx,offset msg3        ;DOS 1.1 --- print message
  75.     mov    ah,9            ;and exit
  76.     int    21h
  77.     ret
  78. whereis2:
  79.     MOV    DI,OFFSET PATH_NAME
  80.     XOR    AL,AL            ;Search for the zero at the end
  81.     CLD                ; of PATH_NAME
  82.     MOV    CX,64            ;Max. length of scan for 0
  83.     REPNZ    SCASB
  84.     MOV    BX,DI
  85.     DEC    BX            ;DS:BX points to end of PATH_NAME
  86.     MOV    DX,0            ;Tell SDIR this is first
  87.     CALL    SDIR            ;Now do the recursive search
  88.     mov    ax,match_count        ;were any matches found?
  89.     or    ax,ax
  90.     jz    whereis8        ;no,jump
  91.     ret                ;yes,just exit
  92. whereis8:
  93.     mov    dx,offset msg2        ;no,print "no match"
  94.     mov    ah,9
  95.     int    21h
  96.     ret
  97.                     ;this is a special crash
  98.                     ;exit, which may be taken
  99.                     ;from inside recursed proc.
  100. whereis9:
  101.     mov    sp,bp
  102.     ret
  103.  
  104. whereis    endp
  105.  
  106.     page
  107.  
  108. ;  This procedure searches all the files in the current directory    
  109. ; looking for a match.  It also prints the full name for each match.    
  110. ;                                    
  111. ;    DS:BX        Pointer to end of current path name        
  112. ;    DS:DX        Old disk transfer area (DTA)            
  113. ;                                    
  114. ; Reads:    Disk Transfer Area (DTA)                
  115. ; Writes:    Disk Transfer Area (DTA)                
  116. ; Calls:    BUILD_NAME, FMATCH, PNAME        
  117. ;        NMATCH, BUILD_STAR_NAME, SSUB    
  118.  
  119. SDIR    PROC    NEAR
  120.     PUSH    SI            ;Need to restore on exit
  121.     PUSH    DX
  122.     CALL    BUILD_NAME        ;Build the absolute search name
  123.     CALL    FMATCH            ;See if there is a match here
  124.     JC    sdir2             ;No match, check subdirectories
  125.     CALL    PNAME            ;Write name of match.
  126. sdir1:
  127.     CALL    NMATCH            ;Find the next match
  128.     JC    sdir2            ;No match, search sub-directories
  129.     CALL    PNAME            ;Match, write absolute name
  130.     JMP    sdir1            ;Look for the next matching name
  131. sdir2:                    ;No match, so try sub-directories.
  132.     POP    DX            ;Restore DTA
  133.     PUSH    DX
  134.     CALL    BUILD_STAR_NAME        ;Search for all directories
  135.     CALL    FMATCH            ;Get first entry
  136.     JC    SDIR5            ;There are no entries
  137.     MOV    SI,DX            ;Put address of DTA into SI
  138.     TEST    [SI].ATTRIBUTE,10H    ;Is it a directory entry?
  139.     JNZ    SDIR4            ;Yes, then search sub-directory
  140. SDIR3:
  141.     CALL    NMATCH            ;No, then find the next match
  142.     JC    SDIR5            ;There are no more entries
  143.     TEST    [SI].ATTRIBUTE,10H    ;Is this a directory?
  144.     JZ    SDIR3            ;No, then try again
  145. SDIR4:
  146.     CMP    [SI].NAME_FOUND,'.'    ;Is this a . or .. directory?
  147.     JE    SDIR3            ;Yes, skip to next directory
  148.     CALL    SSUB            ;Search the sub-directory
  149.     PUSH    AX            ;Now reset the DTA
  150.     MOV    AH,1AH
  151.     INT    21H
  152.     POP    AX
  153.     JMP    SDIR3
  154.  
  155. SDIR5:
  156.     POP    DX
  157.     POP    SI
  158.     RET
  159. SDIR    ENDP
  160.  
  161.     page
  162.  
  163. ; This procedure searches the subdirectory whos name is in the DTA    
  164. ;                                    
  165. ;    DS:BX        End of the current path name            
  166. ;    DS:[DX].NAME_FOUND    Name of subdirectory for search        
  167. ; Reads:    PATH_NAME                        
  168. ; Writes:    PATH_NAME                        
  169. ; Calls:    SDIR                    
  170.  
  171. SSUB    PROC    NEAR
  172.     PUSH    DI
  173.     PUSH    SI
  174.     PUSH    AX
  175.     PUSH    BX
  176.     CLD                ;Set for increment
  177.     MOV    SI,DX            ;Put address of DTA into SI
  178.     ADD    SI,OFFSET NAME_FOUND    ;Set to start of sub-directory name
  179.     MOV    DI,BX            ;DS:DI -- 0 at end of path name
  180. ssub1:                    ;Copy sub-directory to path name
  181.     LODSB                ;Copy one character
  182.     STOSB
  183.     OR    AL,AL            ;Was it a 0?
  184.     JNZ    ssub1            ;No, keep copying
  185.     MOV    BX,DI            ;Set BX to end of new path name
  186.     STD                ;Set flag for decrement
  187.     STOSB                ;Store a 0 at end of string
  188.     MOV    AL,'\'
  189.     STOSB                ;Place '\' at end of path name
  190.     CALL    SDIR            ;Search this new path
  191.     POP    BX            ;Restore the old end-of-path
  192.     MOV    BYTE PTR [BX],0        ;And store a zero here
  193.     POP    AX
  194.     POP    SI
  195.     POP    DI
  196.     RET
  197. SSUB    ENDP
  198.  
  199.     page
  200.  
  201. ; This procedure prints the matched name after the path name        
  202. ;
  203. ;    DS:DX        Pointer to current disk transfer area        
  204. ;                                    
  205. ; Reads:    PATH_NAME, NAME_FOUND (in DTA)                
  206. ; Calls:    pasciiz, CRLF                    
  207.  
  208. PNAME    PROC    NEAR
  209.     PUSH    AX
  210.     PUSH    DX
  211.     MOV    DX,OFFSET PATH_NAME
  212.     MOV    AL,[BX]            ;Save character at end of path
  213.     MOV    BYTE PTR [BX],0        ;Set for end of string    
  214.     CALL    pasciiz
  215.     MOV    [BX],AL            ;Restore character
  216.     POP    DX            ;Recover old pointer
  217.     PUSH    DX
  218.     ADD    DX,OFFSET NAME_FOUND
  219.     CALL    pasciiz
  220.     cmp    byte ptr switch,'g'    ;global switch set?
  221.     je    pname2            ;yes,keep searching
  222.                     ;no, check if user wants 
  223.                     ;to keep looking.
  224.     push    dx            ;save current DTA
  225.     mov    dx,offset msg4        ;print 'More? '
  226.     mov    ah,9
  227.     int    21h
  228.     mov    ah,7            ;read console without echo
  229.     int    21h    
  230.     or    al,20h            ;fold to lower case
  231.     cmp    al,'y'            ;must be y, anything else exits 
  232.     je    pname1
  233.     jmp    whereis9        ;take crash exit
  234. pname1:    mov    dl,al            ;if Y,echo it
  235.     mov    ah,2
  236.     int    21h
  237.     pop    dx            ;restore pointer to DTA
  238. pname2:    CALL    CRLF
  239.     inc    match_count        ;count names displayed
  240.     POP    DX
  241.     POP    AX
  242.     RET
  243. PNAME    ENDP
  244.  
  245.     page
  246.  
  247. ;  This procedure builds an absolute search name from PATH_NAME        
  248. ; followed by FILE_NAME.                        
  249. ;                                    
  250. ; Reads:    FILE_NAME                        
  251. ; Calls:    BUILD        to build the name            
  252.  
  253. BUILD_NAME    PROC    NEAR
  254.     PUSH    SI
  255.     MOV    SI,OFFSET FILE_NAME
  256.     CALL    BUILD
  257.     POP    SI
  258.     RET
  259. BUILD_NAME    ENDP
  260.  
  261. BUILD_STAR_NAME        PROC    NEAR
  262.     PUSH    SI
  263.     MOV    SI,OFFSET STAR_NAME
  264.     CALL    BUILD
  265.     POP    SI
  266.     RET
  267. BUILD_STAR_NAME        ENDP
  268.  
  269. ; This procedure appends the string at DS:SI to PATH_NAME in        
  270. ; PATH_NAME.  It knows where the path name ends from knowing how    
  271. ; long PATH_NAME is.                            
  272. ;                                    
  273. ;    DS:SI        Name of file                    
  274. ;    DS:BX        End of PATH_NAME                
  275. ;                                    
  276. ; Reads:    DS:SI                            
  277. ; Writes:    PATH_NAME                        
  278.  
  279. BUILD    PROC    NEAR
  280.     PUSH    AX
  281.     PUSH    DI
  282.     MOV    DI,BX
  283.     CLD                ;Set direction for increment
  284. build1:
  285.     LODSB                ;Copy one character of name
  286.     STOSB
  287.     OR    AL,AL            ;End of string yet?
  288.     JNZ    build1            ;No, keep copying
  289.     POP    DI
  290.     POP    AX
  291.     RET
  292. BUILD    ENDP
  293.  
  294.     page
  295.  
  296. ;  This procedure finds the first match between the name given by    
  297. ; DS:DX and the directory entries found in the directory PATH_NAME.    
  298. ;                                    
  299. ;    DS:DX        Pointer to current disk transfer area        
  300. ; Returns:                                
  301. ;    CF    0    A match was found                
  302. ;        1    No match found                    
  303. ;    AX        Error code returned:                
  304. ;        2    File not found                    
  305. ;        18    No more files                    
  306. ;    DS:DX        Pointer to new disk transfer area        
  307. ;                                    
  308. ; Reads:    PATH_NAME                        
  309. ; Writes:    dbuff
  310.  
  311. FMATCH    PROC    NEAR
  312.     PUSH    CX
  313.     CMP    DX,0            ;First one?
  314.     JA    ALLOCATE        ;No, then allocate space
  315.     MOV    DX,OFFSET dbuff-TYPE DTA
  316. allocate:
  317.     add    dx,type dta        ;no, then allocate room for new DTA
  318.     MOV    CX,10H            ;Search attribute for files and dirs.
  319.     MOV    AH,1AH            ;Set disk transfer address
  320.     INT    21H
  321.     PUSH    DX            ;Need DX for address of search name
  322.     MOV    DX,OFFSET PATH_NAME
  323.     MOV    AH,4EH            ;Call for "find first match"
  324.     INT    21H
  325.     POP    DX
  326.     POP    CX
  327.     RET                ;Return with carry flag info
  328. FMATCH    ENDP
  329.  
  330.  
  331.     page
  332.  
  333. ; Get next match for filename
  334. ; (very similar to Get first match routine)
  335.  
  336. ; Returns:                                
  337. ;    CF    0    A match was found                
  338. ;        1    No match found                    
  339. ;    AX        Error code returned:                
  340. ;        2    File not found                    
  341. ;        18    No m